/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.bookingmanager.web;

import cz.muni.fi.pa165.bookingmanager.adapters.ReservationAdapter;
import cz.muni.fi.pa165.bookingmanager.adapters.RoomAdapter;
import cz.muni.fi.pa165.bookingmanager.dto.HotelDTO;
import cz.muni.fi.pa165.bookingmanager.dto.ReservationDTO;
import cz.muni.fi.pa165.bookingmanager.dto.RoomDTO;
import cz.muni.fi.pa165.bookingmanager.exceptions.IllegalOrphanException;
import cz.muni.fi.pa165.bookingmanager.exceptions.NonexistentEntityException;
import cz.muni.fi.pa165.bookingmanager.exceptions.PreexistingEntityException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Radek Koubsky
 */
@UrlBinding("/admin/room/${event}")
public class RoomActionBean extends MyActionBean {

    final static Logger log = LoggerFactory.getLogger(RoomActionBean.class);
    private RoomAdapter roomAdapter;
    private ReservationAdapter reservationAdapter;
    private List<RoomDTO> list = new ArrayList<RoomDTO>();
    private String roomNumber;

    public RoomActionBean() throws NamingException {
        Context ctx = new InitialContext();
        roomAdapter = (RoomAdapter) ctx.lookup("java:global/cz.muni.fi.pa165.bookingmanager_booking_manager-web_war_1.0-SNAPSHOT/RoomAdapterImpl!cz.muni.fi.pa165.bookingmanager.adapters.RoomAdapter");
        this.reservationAdapter = (ReservationAdapter) ctx.lookup("java:global/cz.muni.fi.pa165.bookingmanager_booking_manager-web_war_1.0-SNAPSHOT/ReservationAdapterImpl!cz.muni.fi.pa165.bookingmanager.adapters.ReservationAdapter");
    }

    @DefaultHandler
    public Resolution all() {
        log.debug("all()");
        list = roomAdapter.findAllHotelRooms(getContext().getHotel());
        return new ForwardResolution("/backend/hotels/rooms/list.jsp");
    }

    @Before(stages = LifecycleStage.CustomValidation, on = {"add"})
    public void beforeAddValidate() {
        list = roomAdapter.findAllHotelRooms(getContext().getHotel());
    }
    @ValidateNestedProperties(value = {
        @Validate(on = {"add", "save"}, field = "roomNumber", required = true),
        @Validate(on = {"add", "save"}, field = "capacity", required = true, minvalue = 1),
        @Validate(on = {"add", "save"}, field = "price", required = true, minvalue = 1)
    })
    private RoomDTO room;

    public Resolution add() throws IllegalOrphanException, PreexistingEntityException, NonexistentEntityException, Exception {
        log.debug("add() room={}", room);
        room.setHotel(getContext().getHotel());
        roomAdapter.createRoom(room);
        return new RedirectResolution(this.getClass(), "all");
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"delete", "edit", "save"})
    public void loadRoomFrommDatabase() {
        String ids = getContext().getRequest().getParameter("room.id");
        if (ids == null) {
            return;
        }
        room = roomAdapter.getRoomById(Long.parseLong(ids));
    }

    public Resolution edit() {
        log.debug("edit() room={}", room);
        return new ForwardResolution("/backend/hotels/rooms/edit.jsp");
    }

    public Resolution save() throws NonexistentEntityException, IllegalOrphanException, PreexistingEntityException, Exception {
        log.debug("save() room={}", room);
        room.setHotel(getContext().getHotel());
        roomAdapter.updateRoom(room);
        return new RedirectResolution(this.getClass(), "all");
    }

    public Resolution delete() throws NonexistentEntityException, IllegalOrphanException {
        log.debug("delete({})", room.getId());
        List<ReservationDTO> reservations = reservationAdapter.findAllRoomReservations(room);
        for (ReservationDTO res : reservations) {
            reservationAdapter.deleteReservation(res);
        }
        roomAdapter.deleteRoom(room);
        return new RedirectResolution(this.getClass(), "all");
    }

    public RoomDTO getRoom() {
        return room;
    }

    public void setRoom(RoomDTO room) {
        this.room = room;
    }

    public String getRoomNumber() {
        return roomNumber;
    }

    public void setRoomNumber(String roomNumber) {
        this.roomNumber = roomNumber;
    }

    public List<RoomDTO> getList() {
        if (this.list == null) {
            return null;
        }
        return Collections.unmodifiableList(list);
    }

    public void setList(List<RoomDTO> list) {
        this.list = new ArrayList<RoomDTO>();
        this.list.addAll(list);
    }

    public Resolution findRoomByNumber() {
        if (roomNumber == null) {
            return new RedirectResolution(this.getClass(), "all");
        } else {
            RoomDTO searchedRoom = roomAdapter.findRoomByNumber(roomNumber, getContext().getHotel());
            if (searchedRoom != null) {
                list.add(searchedRoom);
            }
            return new ForwardResolution("/backend/hotels/rooms/list.jsp");
        }
    }

    public List<RoomDTO> findAllHotelRooms(HotelDTO hotel) {
        return roomAdapter.findAllHotelRooms(hotel);
    }
}
